package com.mhy.soloader.so;


import android.app.Application;
import android.content.Context;

import java.io.File;

/**
 * AssetsSoApp用于so文件运行时动态加载，加载目录为assets/so/
 * <p>
 * 用法：
 * <p>
 * 1、将原来libs/目录下的  armeabi、x86、 armeabi-v7a...，直接剪切至assets/so/目录下即可。
 * 2、将AndroidManifest.xml中的application设置为：  <application android:name="com.mhy.soloader.so.AssetsSoApp">;
 * 或者 调用 AssetsSoApp.LoadAssetsSo(this);
 * <p>
 * 注解： lib/目录下的so文件，在应用安装时就会输出，时常会报错导致应用无法正常安装。
 * ｛
 * 如：
 * 1、Google Play Store – Can’t install app (Error code: -504)
 * 2、is not page-aligned - will not be able to open it directly from apk
 * 3、Failure [INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2]
 * （此报错修改 aalication属性可以为 android:extractNativeLibs="true"编译的apk可正常运行，可从google play下载却无法安装，还是报第2个错误，
 * 干脆修改为so动态加载，就不会报错了，也可正常安装、运行）
 * ｝
 * <p>
 * 修复原理： so不添加至lib目录，不在应用安装时输出，正常安装。应用运行时，输出对应类型的so库，从该目录下动态加载
 */
public class AssetsSoApp extends Application {
    public void onCreate() {
        super.onCreate();

        CatchAppException(this);    // 捕获运行异常
    }


    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);

        LoadAssetsSo(this);                // assets/so载入
    }


    /**
     * 捕获当前应用的运行异常信息，输出至目录下/sdcard/sc_tool_so/crash/
     */
    public static void CatchAppException(Context context) {
        CrashHandler handler = CrashHandler.getInstance();
        handler.init(context);
    }

    /**
     * assets/so/*.* 文件动态输出、载入
     * <p>
     * 1、自动导出应用assets/so目录下，对应CPU_ABI类型的所有so文件，至应用缓存目录。
     * 2、将该缓存目录，设置为应用的so载入目录
     */
    public static void LoadAssetsSo(Context context) {
        // 生成so输出路径
        String userDataSo = context.getDir("so", Context.MODE_PRIVATE).getAbsolutePath();
        userDataSo += File.separator + android.os.Build.CPU_ABI;// "/data/user/0/sc.game.farm-1/app_so/x86"

        AssetsSo.ExportSo(context, userDataSo);                    // 从assets资源载入对应CPU类型的so，输出至应用数据目录下
        NativeTool.SetSoDirectory(context, userDataSo);    // 设置为so载入目录（加载so时，会检测该目录）
    }
}
